# -*- coding: utf-8 -*-

import sys
from PyQt4 import QtGui
from PyQt4.QtGui import *
from xml.dom import minidom

from S3D.Tests.UI.PuzzleSolveDlg import Ui_PuzzleSolveDlg
from S3D.Tests.UI.PuzzleSolveDlg_MakeDecision import Ui_MakeDecisionDlg
from xml.dom.minidom import Node

PUZZLE_TASK = (
    ("Первый вопрос, ответ на<br/>который B, это вопрос:<br/>",
     "1", "2", "3", "4", "5"),
    ("Единственные два<br/>последовательных вопроса<br/>с одинаковыми ответами это:",
     "6 и 7", "7 и 8", "8 и 9", "9 и 10", "10 и 11"),
    ("Количество вопросов<br/>с ответом E:<br/>",
     "0", "1", "2", "3", "4"),
    ("Количество вопросов<br/>с ответом A:<br/>",
     "4", "5", "6", "7", "8"),
    ("Ответ на этот вопрос<br/>такой же, как и ответ на<br/>вопрос:",
     "1", "2", "3", "4", "5"),
    ("Ответ на вопрос 17:<br/><br/>",
     "С", "D", "E", "ничего из перечисленного", "все перечисленное"),
    ("В алфавите ответ на этот<br/>вопрос и ответ на<br/>следующий вопрос:",
     "отстоят на 4 буквы", "отстоят на 3 буквы", "отстоят на 2 буквы", "отстоят на 1 буквы", "одинаковые"),
    ("Количество вопросов,<br/>чьи ответы - гласные:<br/>",
     "4", "5", "6", "7", "8"),
    ("Следующий вопрос с<br/>таким же ответом,<br/>как и этот:",
     "10", "11", "12", "13", "14"),
    ("Ответ на вопрос 16:<br/><br/>",
     "D", "A", "E", "B", "C"),
    ("Количество вопросов,<br/>предшествующих этому,<br/>с ответом B:",
     "0", "1", "2", "3", "4"),
    ("Количество вопросов,<br/>чьи ответы - согласные:<br/>",
     "четное число", "нечетное число", "полный квадрат", "простое число", "делится на 5"),
    ("Единственный вопрос<br/>с нечетным номером,<br/>чей ответ A:",
     "9", "11", "13", "15", "17"),
    ("Количество вопросов<br/>с ответом D:<br/>",
     "6", "7", "8", "9", "10"),
    ("Ответ на вопрос 12:<br/><br/>",
     "A", "B", "C", "D", "E"),
    ("Ответ на вопрос 10:<br/><br/><br/>",
     "D", "C", "B", "A", "E"),
    ("Ответ на вопрос 6:<br/><br/><br/>",
     "C", "D", "E", "ничего из перечисленного", "все перечисленное"),
    ("Количество вопросов<br/>с ответом A равняется<br/>количеству вопросов<br/>с ответом:",
     "B", "C", "D", "E", "ничего из перечисленного"),
    ("Ответ на этот вопрос:<br/><br/><br/>",
     "A", "B", "C", "D", "E"),
    ("Стандартизованный<br/>тест относится к<br/>интеллигентности как<br/>барометр к:",
     "температуре (только)", "скорости ветра (только)", "широте (только)", "долготе (только)", "все перечисленное")
)

ANSWER_LABEL = "ABCDE"

class SolutionState:
    def __init__(self):
        # by default nothing selected
        self.question = [[False, False, False, False, False] for _ in range(20)]

def buildTable(state):
    table = ""

    # calc statistics
    answers = [0, 0, 0, 0, 0]
    finalAnswers = [0, 0, 0, 0, 0]
    for index in range(20):
        count = 0
        last  = 0
        for answIndex in range(5):
            if not state.question[index][answIndex]:
                answers[answIndex] += 1
                last = answIndex
                count += 1

        if count == 1:
            finalAnswers[last] += 1

    stats = ""
    for index in range(5):
        stats += "%s: %d / %d<br/>" % (ANSWER_LABEL[index], finalAnswers[index], answers[index])

    for row in range(4):
        rowText = ""
        for column in range(5):
            index = column + row * 5

            answers = ""

            for answerIndex in range(5):
                if state.question[index][answerIndex]:
                    answers += '<dt><font color="lightgray"><s>%s) %s<s/></font></dt>' % (ANSWER_LABEL[answerIndex], PUZZLE_TASK[index][answerIndex + 1])
                else:
                    answers += "<dt>%s) %s</dt>"        % (ANSWER_LABEL[answerIndex], PUZZLE_TASK[index][answerIndex + 1])

            header = "%d. %s" % (index + 1, PUZZLE_TASK[index][0])

            cellText = """
                <td>
                <h4>%s</h4>
                <font face="arial" size="3"><dl>%s</dl></font>
                </td>
            """ % (header, answers)

            rowText += cellText

        table += "<tr>%s</tr>" % rowText
            
    res = """
        <font>%s</font>
        <table border="1" bgcolor="white">
            %s
        <table/>""" % (stats, table)

    return res

class Decision:
    TYPE_REMOVE     = 0     # remove & solve contains (<test>, <answer>) tuple in info
    TYPE_SOLVE      = 1
    TYPE_COMMENT    = 2

    def __init__(self, type, info = None):
        self.type = type
        self.info = info

class MakeDecision(QDialog):
    def __init__(self, parent):
        super(MakeDecision, self).__init__(parent)

        self.ui = Ui_MakeDecisionDlg()
        self.ui.setupUi(self)

        self.ui.removeTestNumber.horizontalHeader().hide()
        self.ui.removeTestNumber.verticalHeader().hide()
        self.ui.removeTestNumber.resizeColumnsToContents()
    
        self.ui.solveTestNumber.horizontalHeader().hide()
        self.ui.solveTestNumber.verticalHeader().hide()
        self.ui.solveTestNumber.resizeColumnsToContents()

        self.removeChecks = (self.ui.removeTestA, self.ui.removeTestB, self.ui.removeTestC, self.ui.removeTestD, self.ui.removeTestE)
        self.solveChecks  = (self.ui.solveTestA, self.ui.solveTestB, self.ui.solveTestC, self.ui.solveTestD, self.ui.solveTestE)

    def getCheckedIndex(self, checks):
        for index, p in enumerate(checks):
            if p.isChecked():
                return index

        return -1

    def onAccept(self):
        dec = Decision(self.ui.decisionType.currentIndex())

        if dec.type == Decision.TYPE_COMMENT:
            dec.info = self.ui.comment.toPlainText()
        elif dec.type == Decision.TYPE_REMOVE:
            answer = self.getCheckedIndex(self.removeChecks)
            if answer == -1:
                return

            question = self.ui.removeTestNumber.currentIndex()
            if question is None or not question.isValid():
                return

            question = question.row() * 5 + question.column()

            dec.info = (question, answer)
        else:
            answer = self.getCheckedIndex(self.solveChecks)
            if answer == -1:
                return

            question = self.ui.solveTestNumber.currentIndex()
            if question is None or not question.isValid():
                return

            question = question.row() * 5 + question.column()

            dec.info = (question, answer)

        self.decision = dec
        self.accept()

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        self.ui = Ui_PuzzleSolveDlg()
        self.ui.setupUi(self)
        self.show()

        self.ui.decisionList.horizontalHeader().hide()

        self.decisionList = []
        self.updateTable()

        self.autoload()

    def closeEvent(self, e):
        self.autosave()

    def autoload(self):
        try:
            doc = minidom.parse("puzzle_solution.xml")
        except:
            return

        del self.decisionList[:]
        
        root = doc.getElementsByTagName("solution")[0]

        for elem in root.childNodes:
            if elem.nodeType != Node.ELEMENT_NODE:
                continue

            if elem.tagName == "comment":
                self.decisionList.append(Decision(Decision.TYPE_COMMENT, elem.getAttribute("text")))
            elif elem.tagName == "remove":
                question = int(elem.getAttribute("question"))
                answer   = int(elem.getAttribute("answer"))
                self.decisionList.append(Decision(Decision.TYPE_REMOVE, (question, answer)))
            elif elem.tagName == "solve":
                question = int(elem.getAttribute("question"))
                answer   = int(elem.getAttribute("answer"))
                self.decisionList.append(Decision(Decision.TYPE_SOLVE,  (question, answer)))

        self.updateDecisions()
        self.updateTable()

    def autosave(self):
        root = minidom.Element("solution")

        for p in self.decisionList:
            if p.type == Decision.TYPE_COMMENT:
                elem = minidom.Element("comment")
                elem.setAttribute("text", p.info)
            elif p.type == Decision.TYPE_REMOVE:
                elem = minidom.Element("remove")
                elem.setAttribute("question", str(p.info[0]))
                elem.setAttribute("answer",   str(p.info[1]))
            else:
                elem = minidom.Element("solve")
                elem.setAttribute("question", str(p.info[0]))
                elem.setAttribute("answer",   str(p.info[1]))

            root.appendChild(elem)

        text = root.toprettyxml(encoding="UTF-8")

        f = open("puzzle_solution.xml", "wb")
        f.write(text)
        f.close()

    def onMakeDecision(self):
        dlg = MakeDecision(self)
        if dlg.exec_() != QDialog.Accepted:
            return

        print("Decision: %s" % str(dlg.decision.info))

        self.decisionList.append(dlg.decision)

        self.updateDecisions()
        self.updateTable()

        self.autosave()

    def updateTable(self):
        state = SolutionState()

        for p in self.decisionList:
            if p.type == Decision.TYPE_COMMENT:
                continue

            q, ans = p.info

            if p.type == Decision.TYPE_REMOVE:
                state.question[q][ans] = True
            else:
                for index in range(5):
                    if index != ans:
                        state.question[q][index] = True

        self.ui.table.setText(buildTable(state))

    def updateDecisions(self):
        self.ui.decisionList.clear()

        self.ui.decisionList.setColumnCount(1)
        self.ui.decisionList.setRowCount(len(self.decisionList))

        for index, p in enumerate(self.decisionList):
            if p.type == Decision.TYPE_COMMENT:
                text = "%s" % p.info
            elif p.type == Decision.TYPE_REMOVE:
                quest, answ = p.info
                text = "REMOVE: %d. %s" % (quest + 1, ANSWER_LABEL[answ])
            else:
                quest, answ = p.info
                text = "SOLVE: %d. %s" % (quest + 1, ANSWER_LABEL[answ])

            self.ui.decisionList.setItem(index, 0, QTableWidgetItem(text))

        self.ui.decisionList.resizeRowsToContents()
        self.ui.decisionList.resizeColumnsToContents()

        self.ui.decisionList.setCurrentCell(len(self.decisionList) - 1, 0)

if __name__ == '__main__':
    qApp = QtGui.QApplication(sys.argv)

    wnd = MainWindow()

    sys.exit(qApp.exec_())